package com.a0soft.gphone.aTruffleHog.wnd.stat;
/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 3, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * Copyright(C) 2011 
 *   Sam Lu <ysl.sam.lu (at) gmail.com>
 *
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.a0soft.gphone.aTruffleHog.R;
import com.a0soft.gphone.aTruffleHog.analytic.AnalyticsUtil;
import com.a0soft.gphone.aTruffleHog.di.DeviceInfo;
import com.a0soft.gphone.aTruffleHog.di.DeviceInfoKey;
import com.a0soft.gphone.aTruffleHog.srvc.HttpConnSrvc;
import com.a0soft.gphone.aTruffleHog.util.aDebug;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class RootedStatsFrg extends BaseStatFragment {
    protected static final int TYPE_MY_DEVICE = 1;
    protected static final int TYPE_ALL_DEVICES = 2;
    protected static final int TYPE_USER_DEFINED = 3;
    
    private ArrayList<RootedData>   m_data;
    
    private static final String LOG_TAG = RootedStatsFrg.class.getSimpleName();
    
    ////////////////////////////////////////
    public static RootedStatsFrg 
    NewInstance(Context ctx, int nType, String strMID) 
    {
        RootedStatsFrg frg = new RootedStatsFrg();
        if (nType == TYPE_MY_DEVICE) {
            DeviceInfo di = DeviceInfo.GetInstance(ctx);
            strMID = di.GetString(DeviceInfoKey.K.ST_MID);
        }
        
        SetTypeAndMID(frg, nType, strMID);
        return frg;
    }  
    
    @Override public void 
    onActivityCreated(Bundle bdSavedInstanceState)
    {
        super.onActivityCreated(bdSavedInstanceState);
        if (aDebug.ENABLED) aDebug.d(LOG_TAG, "onActivityCreated(): m_nType=" + m_nType);
        
        String strPage;
        switch (m_nType) {
        case TYPE_MY_DEVICE: strPage = AnalyticsUtil.PAGE_STAT_ROOTED_MY; break;
        case TYPE_USER_DEFINED: strPage = AnalyticsUtil.PAGE_STAT_ROOTED_USER_DEFINED + "/" + m_strUserDefinedMID; break;
        default: strPage = AnalyticsUtil.PAGE_STAT_ROOTED_ALL; break;
        }
        AnalyticsUtil.GetInstance(getActivity()).TrackPageView(strPage);
    }
    
    @Override public View 
    onCreateView(LayoutInflater inflater, ViewGroup vgContainer,
                 Bundle bdSavedInstanceState) 
    {
        View vRoot = super.onCreateView(inflater, vgContainer, bdSavedInstanceState);
        
        if (!getActivity().isFinishing())
            _GetRootedStats(false);
        
        return vRoot;
    }
    
    private void
    _SetData(JSONObject json)
    {
        try {
            m_lDataTime = json.getLong("t");
            
            JSONArray data = json.getJSONArray("d");
            final int N = data.length();
            if (aDebug.ENABLED)
                aDebug.d(LOG_TAG, "N=" + N);
            
            if (N <= 0) {
                m_data = new ArrayList<RootedData>(1);
            }
            else {
                m_data = new ArrayList<RootedData>(N);
                for (int i = 0; i < N; i++) {
                    JSONObject obj = data.getJSONObject(i);
                    RootedData rooted = new RootedData();
                    rooted.m_fPercentage = (float)obj.getDouble("p");
                    rooted.m_bRooted = obj.getBoolean("r");
                    rooted.m_lCount = obj.getLong("c");
                    
                    m_data.add(rooted);
                }
            }
        }
        catch (JSONException e) {
            if (aDebug.ENABLED)
                aDebug.d(LOG_TAG, "_SetData()", e);
            m_data = new ArrayList<RootedData>(1);
        }
        SetStatData(m_data);
        
        Context ctx = getActivity();
        if (ctx == null) return;

        _AddFakeData(ctx);
        _SortData();

        DeviceInfo di = DeviceInfo.GetInstance(ctx);
        boolean bMyDeviceIsRooted = di.GetBoolean(DeviceInfoKey.K.ST_ROOTED);
        
        String strManufacture = di.GetString(DeviceInfoKey.K.ST_MANUFACTURE);
        String strModel = di.GetString(DeviceInfoKey.K.ST_MODEL);
        if (!strModel.toLowerCase().startsWith(strManufacture.toLowerCase())) {
            strModel = strManufacture + " " + strModel;
        }
        m_strMy = getString(R.string.rooted_of_your_device, 
                            strModel,
                            getString(bMyDeviceIsRooted ? R.string.rooted : R.string.not_rooted));
        
        m_nMyIdx = -1;
        final int N = m_data.size();
        for (int i = 0; i < N; i++) {
            RootedData rooted = (RootedData)m_data.get(i);
            if (rooted.m_bRooted == bMyDeviceIsRooted) {
                m_nMyIdx = i;
                break;
            }
        }

        if (m_nMyIdx == -1) {
            //not found
        }
        
        SetDataFinished();
    }
    
    private void
    _SortData()
    {
        if (m_data.size() <= 1)
            return;
        
        Collections.sort(m_data, new Comparator<RootedData>() {
            @Override public int 
            compare(RootedData rooted1, RootedData rooted2)
            {
                float f = rooted2.m_fPercentage - rooted1.m_fPercentage;
                if (f < 0) return -1; else if (f > 0) return 1;
                return (!rooted1.m_bRooted) ? -1 : 1;
            }
        });
    }
    
    private void
    _AddFakeData(Context ctx)
    {        
        DeviceInfo di = DeviceInfo.GetInstance(ctx);
        final boolean bRooted = di.GetBoolean(DeviceInfoKey.K.ST_ROOTED);
        
        //no stats, add current device info
        if (m_data.size() == 0) { 
            m_lDataTime = System.currentTimeMillis();
            
            RootedData os = new RootedData();
            os.m_lCount = 1;
            os.m_fPercentage = 1f;
            os.m_bRooted = bRooted;
            
            m_data.add(os);
        }
        
        //add one if no current device info
        boolean bHasMyDeviceInfo = false;
        long lMaxCount = Long.MIN_VALUE;
        RootedData osMax = null;
        for (RootedData rooted: m_data) {
            if (!bHasMyDeviceInfo && 
                rooted.m_bRooted == bRooted) {
                bHasMyDeviceInfo = true;
            }
            if (lMaxCount < rooted.m_lCount) {
                lMaxCount = rooted.m_lCount;
                osMax = rooted;
            }
        }
        
        //allocate 10% for rooted device and 50% for non-rooted
        if (!bHasMyDeviceInfo) { 
            m_lDataTime = System.currentTimeMillis();
            
            float fExcludePercentage = bRooted ? 0.1f : 0.5f;
            
            RootedData rooted = new RootedData();
            rooted.m_fPercentage = osMax.m_fPercentage * fExcludePercentage;
            rooted.m_lCount = Math.max(1, (long)(lMaxCount * fExcludePercentage));
            rooted.m_bRooted = bRooted;
            
            m_data.add(rooted);
            
            osMax.m_fPercentage -= rooted.m_fPercentage;
            osMax.m_lCount -= rooted.m_lCount;
        }
    }
    
    private void
    _GetRootedStats(boolean bRedownloadFromServer)
    {
        Context ctx = getActivity();
        
        DeviceInfo di = DeviceInfo.GetInstance(ctx);
        final String strDID = di.GetString(DeviceInfoKey.K.UR_ID);

        if (m_nType == TYPE_MY_DEVICE || m_nType == TYPE_USER_DEFINED) {
            final String strMID = m_strUserDefinedMID;
            HttpConnSrvc.RequestUserDefinedRootedStats(ctx, strMID.hashCode(), 
                strMID, strDID, bRedownloadFromServer);     
        }
        else if (m_nType == TYPE_ALL_DEVICES) {
            HttpConnSrvc.RequestAllRootedStats(ctx, strDID, bRedownloadFromServer);  
        }
    }

    @Override protected boolean 
    IsMyDownloadCmd(int nCmd)
    {
        if (m_nType == TYPE_ALL_DEVICES)
            return (nCmd == HttpConnSrvc.CMD_GET_ROOTED_STATS_ALL);
        else if (m_nType == TYPE_MY_DEVICE || m_nType == TYPE_USER_DEFINED)
            return (nCmd == m_strUserDefinedMID.hashCode());
        
        return false;
    }
    
    @Override protected void 
    OnMyDownloadSuccess(int nCmd, JSONObject json)
    {
        super.OnMyDownloadSuccess(nCmd, json);
        
        _SetData(json);
    }

    @Override protected void
    SetListItemView(StatData stat, ListItemTagData tag)
    {
        RootedData rooted = (RootedData)stat;
        
        tag.m_tvVersion.setText(rooted.m_bRooted ? R.string.rooted : R.string.not_rooted);
        tag.m_tvAPI.setVisibility(View.GONE);
    }
        
    ////////////////////////////////////
    private static class RootedData extends StatData {
        private boolean m_bRooted;
    }
}
